#include "socket_local_write.h"

#include "pfunc.h"
#include "socket_private_acl.h"
#include "business_def.h"
#include "Log.h"
// #include "strchange.h"
#include "dtypedef.h"
#ifdef __linux__
#include<algorithm>
#endif
#ifdef WIN32
#define usleep(x) Sleep(x)
#endif

bool comp_dev(const Dev &a, const Dev &b) {
	return a.devInfo.desc < b.devInfo.desc;
};

SocketLocalWrite::SocketLocalWrite(void)
	: running(true)
	, socket_acl(NULL)
	, queueforwrite(QueueDataSingle<SocketLocalWriteItem>::getInstance())
	, m_CacheDataObj(BusinessDef::getInstance())
{
	queueforwrite->setQueueDesc("local_socket_write");
}

SocketLocalWrite::~SocketLocalWrite(void)
{
	running = false;
}

void SocketLocalWrite::setPrivateDataPtr(SocketPrivate_ACL *socket_acl_)
{
	if (NULL != socket_acl_)
	{
		socket_acl = socket_acl_;
	}
}

void* SocketLocalWrite::run()
{
	if (NULL == socket_acl) 
	{
		CLogger::createInstance()->Log(MsgError,
			"SocketLocalWrite start fail for socket_acl is NULL"
			",[%s %s %d]!"
			, __FILE__, __FUNCTION__, __LINE__);
		return 0;
	}
	while(running)
	{
		InitDev();
		PValueUp();
		usleep(1);
	}
	return NULL;
}

void SocketLocalWrite::InitDev()
{
	std::vector<unsigned long long> ips;
	if (socket_acl->getNewAddClient(ips))
	{
		std::vector<pyfree::Dev> devs_;
		m_CacheDataObj->getDevs(devs_,true);
		sort(devs_.begin(), devs_.end(), comp_dev);
		unsigned int devSize = static_cast<unsigned int>(devs_.size());
		for (std::vector<unsigned long long>::iterator itip = ips.begin(); itip!=ips.end(); ++itip)
		{
			for (unsigned int i = 0; i<devSize; ++i)
			{
				devInfoUp(*itip
					, static_cast<int>(devs_[i].devInfo.devID)
					, devs_[i].devInfo.devType
					// , ASCII2UTF_8(devs_[i].devInfo.desc)
					, devs_[i].devInfo.desc
					);
				for (std::map<unsigned int,pyfree::PInfo>::iterator itp = devs_[i].pInfo.begin(); 
					itp != devs_[i].pInfo.end(); ++itp)
				{
					pointInfoUp(*itip
						,static_cast<int>(devs_[i].devInfo.devID)
						, itp->second.pID
						, itp->second.pType
						// , ASCII2UTF_8(itp->second.desc)
						, itp->second.desc
						, itp->second.defVal);
				}
			}
		}
		ips.clear();
	}
}

void SocketLocalWrite::devInfoUp(unsigned long long _ipInt,int devID, int devType, std::string desc)
{
	try {
		int idx = 0;
		unsigned char buf[512] = { 0 };
		buf[idx++] = 0XF3;
		//信息长度
		buf[idx++] = 0xf0;		//1-Len_L
		buf[idx++] = 0xf0;		//2-Len_H
								//devid
		buf[idx++] = (unsigned char)(devID & 0xff);
		buf[idx++] = (unsigned char)((devID >> 8) & 0xff);
		buf[idx++] = (unsigned char)((devID >> 16) & 0xff);
		buf[idx++] = (unsigned char)((devID >> 24) & 0xff);
		//devtype
		buf[idx++] = (unsigned char)(devType & 0xff);
		buf[idx++] = (unsigned char)((devType >> 8) & 0xff);
		buf[idx++] = (unsigned char)((devType >> 16) & 0xff);
		buf[idx++] = (unsigned char)((devType >> 24) & 0xff);

		memcpy(buf + idx, desc.c_str(), desc.length());
		idx += static_cast<int>(desc.length());

		buf[1] = static_cast<unsigned char>(idx & 0xff);
		buf[2] = static_cast<unsigned char>((idx >> 8) & 0xff);
		//
		unsigned char m_end = 0xFF;
		memcpy(buf + idx, &m_end, 1);
		idx++;

		unsigned char _buf[256] = { 0 };
		int nLen = pyfree::code(buf, idx, _buf);
		bool mapIpF = true;
		int ret = socket_acl->Write(_ipInt, (const char*)_buf, nLen, mapIpF);
		if (ret != nLen && mapIpF) 
		{
			CLogger::createInstance()->Log(MsgInfo,
				"send dev info data to IpLong(%lu) and MapIpF(%d): Len(%d), Ret(%d). [%s %s %d]"
				, _ipInt, static_cast<int>(mapIpF), nLen, ret
				, __FILE__, __FUNCTION__, __LINE__);
		}
	}
	catch (const std::exception& e)
	{
		CLogger::createInstance()->Log(MsgError,
			"SocketLocalWrite::devInfoUp have error[%s]. [%s %s %d]"
			, e.what()
			, __FILE__, __FUNCTION__, __LINE__);
	}
}

void SocketLocalWrite::pointInfoUp(unsigned long long _ipInt
	, int devID, int pID, int pType, std::string desc, float defval)
{
	try {
		int idx = 0;
		unsigned char buf[512] = { 0 };
		buf[idx++] = 0XF4;
		//信息长度
		buf[idx++] = 0xf0;		//1-Len_L
		buf[idx++] = 0xf0;		//2-Len_H
								//devid
		buf[idx++] = (unsigned char)(devID & 0xff);
		buf[idx++] = (unsigned char)((devID >> 8) & 0xff);
		buf[idx++] = (unsigned char)((devID >> 16) & 0xff);
		buf[idx++] = (unsigned char)((devID >> 24) & 0xff);
		//pid
		buf[idx++] = (unsigned char)(pID & 0xff);
		buf[idx++] = (unsigned char)((pID >> 8) & 0xff);
		buf[idx++] = (unsigned char)((pID >> 16) & 0xff);
		buf[idx++] = (unsigned char)((pID >> 24) & 0xff);
		//ptype
		buf[idx++] = (unsigned char)(pType & 0xff);
		buf[idx++] = (unsigned char)((pType >> 8) & 0xff);
		buf[idx++] = (unsigned char)((pType >> 16) & 0xff);
		buf[idx++] = (unsigned char)((pType >> 24) & 0xff);
		//defval
		unsigned char*vavch = (unsigned char*)&defval;
		buf[idx++] = vavch[3];
		buf[idx++] = vavch[2];
		buf[idx++] = vavch[1];
		buf[idx++] = vavch[0];
		vavch = NULL;
		memcpy(buf + idx, desc.data(), desc.length());
		idx += static_cast<int>(desc.length());

		buf[1] = static_cast<unsigned char>(idx & 0xff);
		buf[2] = static_cast<unsigned char>((idx >> 8) & 0xff);
		unsigned char m_end = 0xFF;
		memcpy(buf + idx, &m_end, 1);
		idx++;

		unsigned char _buf[256] = { 0 };
		int nLen = pyfree::code(buf, idx, _buf);
		bool mapIpF = true;
		int ret = socket_acl->Write(_ipInt, (const char*)_buf, nLen, mapIpF);
		if (ret != nLen && mapIpF) 
		{
			CLogger::createInstance()->Log(MsgInfo,
				"send point info data to IpLong(%lu) and MapIpF(%d): Len(%d), Ret(%d). [%s %s %d]"
				, _ipInt, static_cast<int>(mapIpF), nLen, ret
				, __FILE__, __FUNCTION__, __LINE__);
		}
	}
	catch (const std::exception& e)
	{
		CLogger::createInstance()->Log(MsgError,
			"SocketLocalWrite::pointInfoUp have error[%s]. [%s %s %d]"
			, e.what()
			, __FILE__, __FUNCTION__, __LINE__);
	}
}

void SocketLocalWrite::PValueUp()
{
	unsigned long long _ipInt = 0;
	unsigned char buf[512] = { 0 };
	int len = this->getBuffer(_ipInt, buf);
	if (len > 0 && !socket_acl->emptyClients()) 
	{
		int ret = socket_acl->Write((const char*)buf, len);
		if (ret != len) 
		{
			CLogger::createInstance()->Log(MsgInfo,
				"send data: %d, buf %d. [%s %s %d]", len, ret
				, __FILE__, __FUNCTION__, __LINE__);
		}
		// CLogger::createInstance()->Log(MsgInfo,
		// 	"send data: %d, buf %d. [%s %s %d]", len, ret
		// 	, __FILE__, __FUNCTION__, __LINE__);
	}
}

int SocketLocalWrite::getBuffer(unsigned long long &_ipInt, unsigned char* _buf)
{
	SocketLocalWriteItem it;
	if (queueforwrite->getFirst(it))
	{
		try {
			int idx = 0;
			unsigned char buf[512] = { 0 };
			buf[idx++] = 0XF5;
			//信息长度
			buf[idx++] = 0xf0;		//1-Len_L
			buf[idx++] = 0xf0;		//2-Len_H
									//devid
			buf[idx++] = (unsigned char)(it.devID & 0xff);
			buf[idx++] = (unsigned char)((it.devID >> 8) & 0xff);
			buf[idx++] = (unsigned char)((it.devID >> 16) & 0xff);
			buf[idx++] = (unsigned char)((it.devID >> 24) & 0xff);
			//pid
			buf[idx++] = (unsigned char)(it.pID & 0xff);
			buf[idx++] = (unsigned char)((it.pID >> 8) & 0xff);
			buf[idx++] = (unsigned char)((it.pID >> 16) & 0xff);
			buf[idx++] = (unsigned char)((it.pID >> 24) & 0xff);
			//sc
			buf[idx++] = (unsigned char)(it.evtTimeS & 0xff);
			buf[idx++] = (unsigned char)((it.evtTimeS >> 8) & 0xff);
			buf[idx++] = (unsigned char)((it.evtTimeS >> 16) & 0xff);
			buf[idx++] = (unsigned char)((it.evtTimeS >> 24) & 0xff);
			//msc
			buf[idx++] = (unsigned char)(it.evtTimeMS & 0xff);
			buf[idx++] = (unsigned char)((it.evtTimeMS >> 8) & 0xff);
			buf[idx++] = (unsigned char)((it.evtTimeMS >> 16) & 0xff);
			buf[idx++] = (unsigned char)((it.evtTimeMS >> 24) & 0xff);
			//val
			unsigned char*vavch = (unsigned char*)&it.val;
			buf[idx++] = vavch[3];
			buf[idx++] = vavch[2];
			buf[idx++] = vavch[1];
			buf[idx++] = vavch[0];
			vavch = NULL;
			buf[1] = static_cast<unsigned char>(idx & 0xff);
			buf[2] = static_cast<unsigned char>((idx >> 8) & 0xff);
			unsigned char m_end = 0xFF;
			memcpy(buf + idx, &m_end, 1);
			idx++;
			//
			memset(_buf, 0, 2 * idx);
			int nLen = pyfree::code(buf, idx, _buf);
			if (!queueforwrite->removeFirst())
			{
				CLogger::createInstance()->Log(MsgInfo,
					"queueforwrite removeFirst failed! [%s %s %d]"
					, __FILE__, __FUNCTION__, __LINE__);
			}
			return nLen;
		}
		catch (const std::exception& e)
		{
			CLogger::createInstance()->Log(MsgError,
				"SocketLocalWrite::getBuffer have error[%s]. [%s %s %d]"
				, e.what()
				, __FILE__, __FUNCTION__, __LINE__);
			return -1;
		}
		catch (...) 
		{
			CLogger::createInstance()->Log(MsgError,
				"write item info to socket failed! have error. [%s %s %d]"
				, __FILE__, __FUNCTION__, __LINE__);
			return -1;
		}
	}
	else {
		return -1;
	}
}